<?php

use think\facade\Db;
use think\facade\Route;

// 应用公共文件
/**
 * 传递一个父级分类ID返回所有子分类
 * @param $cate
 * @param $pid
 * @return array
 */
function getChildsRule($rules, $pid)
{
    $arr = [];
    foreach ($rules as $v) {
        if ($v['pid'] == $pid) {
            $arr[] = $v;
            $arr = array_merge($arr, getChildsRule($rules, $v['id']));
        }
    }
    return $arr;
}

/**
 * 格式化系统设置表中的setup数据
 * @param $system
 * @return mixed
 */
function sysgem_setup($system)
{
    foreach ($system as $k => $v) {
        if ($system[$k]['setup']) {
            $system[$k]['setup'] = string2array($v['setup']);
            if (array_key_exists('options', $system[$k]['setup'])) {
                $system[$k]['setup']['options'] = explode("\n", $system[$k]['setup']['options']);
                foreach ($system[$k]['setup']['options'] as $kk => $vv) {
                    $system[$k]['setup']['options'][$kk] = trim_array_element(explode("|", $system[$k]['setup']['options'][$kk]));

                }
            }
        }
    }
    return $system;
}

/**
 * 过滤数组元素前后空格 (支持多维数组)
 * @param $array 要过滤的数组
 * @return array|string
 */
function trim_array_element($array)
{
    if (!is_array($array))
        return trim($array);
    return array_map('trim_array_element', $array);
}

/**
 * 根据数组中某个字段重新分组
 * @param {dataArr:需要分组的数据；keyStr:分组依据}
 * @return: array
 */
function array_group(array $dataArr, string $keyStr): array
{
    $newArr = [];
    foreach ($dataArr as $k => $val) {
        $newArr[$val[$keyStr]] = $val;
    }
    return $newArr;
}

function array_group2(array $dataArr, string $keyStr): array
{
    $newArr = [];
    foreach ($dataArr as $k => $val) {
        $newArr[$val[$keyStr]][] = $val;
    }
    return $newArr;
}

/***
 * 对象转数组
 * @param $object
 * @return array
 */
function object2array($object)
{
    $array = array();
    if (is_object($object)) {
        foreach ($object as $key => $value) {
            $array[$key] = $value;
        }
    } else {
        $array = $object;
    }
    return $array;
}

/***
 * 字符串转数组
 * @param $info
 * @return array
 */
function string2array($info)
{
    if ($info == '') return array();
    eval("\$r = $info;");
    return $r;
}

/***
 * 数组转字符串
 * @param $info
 * @return string
 */
function array2string($info)
{
    //删除空格，某些情况下字段的设置会出现换行和空格的情况
    if (is_array($info)) {
        if (array_key_exists('options', $info)) {
            $info['options'] = trim($info['options']);
        }
    }
    if ($info == '') return '';
    if (!is_array($info)) {
        //删除反斜杠
        $string = stripslashes($info);
    }
    foreach ($info as $key => $val) {
        $string[$key] = stripslashes($val);
    }
    $setup = var_export($string, TRUE);
    return $setup;
}

/***
 * 日期筛选格式化
 * @param $dateran
 * @return array
 */
function get_dateran($dateran)
{
    if ($dateran) {
        $dateran = explode(" 至 ", $dateran);
    }
    if (is_array($dateran) && count($dateran) == 2) {
        $dateran[0] = strtotime($dateran[0]);
        $dateran[1] = strtotime($dateran[1]) + 24 * 60 * 60 - 1;
    }
    return $dateran;
}

/***
 * 格式化面包导航(用户后台面包导航)
 * @param $data
 * @return array
 */
function format_bread_crumb($data)
{
    $result = array();
    if (!empty($data)) {
        $data = array_reverse($data);
        if (count($data) == 4) {
            //非常规 添加或修改
            $result['right'] = $data[1];
            $result['left'][0] = $data[1]['title'];
            //查看是添加还是修改
            $result['left'][1] = $data[2]['title'] . '-' . str_replace('操作-', '', $data[3]['title']);
        } else if (count($data) == 3) {
            //常规 添加或修改
            $result['right'] = $data[1];
            $result['left'][0] = $data[1]['title'];
            //查看是添加还是修改
            $result['left'][1] = str_replace('操作-', '', $data[2]['title']);
        } else if (count($data) == 2) {
            //常规 列表
            $result['right'] = $data[1];
            $result['left'][0] = $data[1]['title'];
            $result['left'][1] = '列表';
        } else {
            //单独定义
            $result['right'] = $data[0];
            $result['left'][0] = $data[0]['title'];
            $result['left'][1] = '';
        }
    }
    //内容管理重构数组
    if (\think\facade\Request::has('cate')) {
        //判断当前方法是添加、修改、列表
        $action = \think\facade\Request::action();
        if ($action == 'add') {
            $action = '添加';
        } else if ($action == 'edit') {
            $action = '修改';
        } else {
            $action = '列表';
        }
        //内容管理
        $cate = \think\facade\Request::param('cate');
        //调用当前栏目名称
        $catname = \app\common\model\Cate::where('id', $cate)->value('catname');
        $result['right'] = [
            'url' => '',
            'title' => $catname,
            'icon' => '',
        ];
        $result['left'][0] = $catname;
        $result['left'][1] = $action;
    }

    return $result;
}

/**
 * 产生随机字串，可用来自动生成密码 默认长度6位 字母和数字混合
 * @param string $len 长度
 * @param string $type 字串类型
 * 0 字母 1 数字 其它 混合
 * @param string $addChars 额外字符
 * +----------------------------------------------------------
 * @return string
 * +----------------------------------------------------------
 */
function rand_string($len = 6, $type = '', $addChars = '')
{
    $str = '';
    switch ($type) {
        case 0:
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $addChars;
            break;
        case 1:
            $chars = str_repeat('0123456789', 3);
            break;
        case 2:
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $addChars;
            break;
        case 3:
            $chars = 'abcdefghijklmnopqrstuvwxyz' . $addChars;
            break;
        case 4:
            $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借" . $addChars;
            break;
        case 5:
            $chars = $addChars;
            break;
        default :
            // 默认去掉了容易混淆的字符oOLl和数字01，要添加请使用addChars参数
            $chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz123456789' . $addChars;
            break;
    }
    if ($len > 10) {//位数过长重复字符串一定次数
        $chars = $type == 1 ? str_repeat($chars, $len) : str_repeat($chars, 5);
    }
    if ($type != 4) {
        $chars = str_shuffle($chars);
        $str = substr($chars, 0, $len);
    } else {
        // 中文随机字
        for ($i = 0; $i < $len; $i++) {
            $str .= msubstr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1);
        }
    }
    return $str;
}

/**
 * 无限分类-权限
 * @param $cate [] 栏目
 * @param string $lefthtml 分隔符
 * @param int $pid 父ID
 * @param int $lvl 层级
 * @return array
 */
function tree($cate, $lefthtml = '|— ', $pid = 0, $lvl = 0)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v['lvl'] = $lvl + 1;
            $v['lefthtml'] = str_repeat($lefthtml, $lvl);
            $v['ltitle'] = $v['lefthtml'] . $v['title'];
            $arr[] = $v;
            $arr = array_merge($arr, tree($cate, $lefthtml, $v['id'], $lvl + 1));
        }
    }
    return $arr;
}

//无限分级
function getTree($data, $pId, $ruleArr = array())
{
    $tree = [];
    foreach ($data as $k => $v) {

        $v['field'] = 'rules[]';
        if ($v['pid'] == $pId) {
            //父亲找到儿子
            if (getTree($data, $v['id'], $ruleArr)) {
                $v['children'] = getTree($data, $v['id'], $ruleArr);
            } else {
                if (in_array($v['id'], $ruleArr)) {
                    $v['checked'] = true;
                } else {
                    $v['checked'] = false;
                }
            }
            $tree[] = $v;
        }
    }
    return $tree;
}

/**
 * 获取文件夹中的文件,含目录
 * @param $path
 * @param string $exts
 * @param array $list
 * @return array
 */
function dir_list($path, $exts = '', $list = array())
{
    $path = dir_path($path);
    $files = glob($path . '*');
    foreach ($files as $v) {
        $fileext = fileext($v);
        if (!$exts || preg_match("/\.($exts)/i", $v)) {
            $list[] = $v;
            if (is_dir($v)) {
                $list = dir_list($v, $exts, $list);
            }
        }
    }
    return $list;
}

/**
 * 补齐目录后的/
 * @param $path 目录
 * @return string
 */
function dir_path($path)
{
    $path = str_replace('\\', '/', $path);
    if (substr($path, -1) != '/') $path = $path . '/';
    return $path;
}

/**
 * 查找文件后缀
 * @param $filename 文件名称
 * @return string 后缀名称（如：html）
 */
function fileext($filename)
{
    return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
}

/**
 * PHP格式化字节大小
 * @param number $size 字节数
 * @param string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 */
function format_bytes($size, $delimiter = '')
{
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}

/**
 * 无限分类-栏目
 * @param $cate
 * @param string $lefthtml
 * @param int $pid
 * @param int $lvl
 * @return array
 */
function tree_cate($cate, $lefthtml = '|— ', $pid = 0, $lvl = 0)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v['lvl'] = $lvl + 1;
            $v['lefthtml'] = str_repeat($lefthtml, $lvl);
            $v['lcatname'] = $v['lefthtml'] . $v['catname'];
            $arr[] = $v;
            $arr = array_merge($arr, tree_cate($cate, $lefthtml, $v['id'], $lvl + 1));
        }
    }
    return $arr;
}

/**
 * 获取所有模版
 * @return mixed
 */
function getTemplate($model = '')
{
    $viewPath = config('view.view_dir_name');
    $viewSuffix = config('view.view_suffix');
    $viewPath = $viewPath ? $viewPath : 'view';
    $filepath = root_path() . $viewPath . '/' . config('app.default_app') . '/';
    $tempfiles = dir_list($filepath, $viewSuffix);
    $arr = [];
    foreach ($tempfiles as $key => $file) {
        $dirname = basename($file);
        if ($model) {
            if (strstr($dirname, $model . '_')) {
                $arr[$key]['value'] = substr($dirname, 0, strrpos($dirname, '.'));
                $arr[$key]['filename'] = $dirname;
                $arr[$key]['filepath'] = $file;
            }
        } else {
            $arr[$key]['value'] = substr($dirname, 0, strrpos($dirname, '.'));
            $arr[$key]['filename'] = $dirname;
            $arr[$key]['filepath'] = $file;
        }
    }
    return $arr;
}

//初始表单
function getform($form, $info, $value = '')
{
    $type = $info['type'];
    return $form->$type($info, $value);
}

/**
 * @param $time
 * @param $format
 * @return string
 * 将时间戳转换为日期格式
 */
function toDate($time, $format = 'Y-m-d H:i:s')
{
    if (empty ($time)) {
        return '';
    }
    $format = str_replace('#', ':', $format);
    return date($format, $time);
}

/**
 * @param $table 表名
 * @param $field 字段名
 * @param $aid 资源id
 * @param string $fid 数据id
 * @param string $type 操作类型
 */
function setAttachment($table, $field, $aid = '', $fid = '', $more = 0)
{
    $pk = Db::name($table)->getPk();
    if ($table == 'system') {
        $value = Db::name($table)->where($pk, $fid)->value('value');
    } else {
        $value = Db::name($table)->where($pk, $fid)->value($field);
    }
    if ($value) {
        $type = 'update';
    } else {
        $type = 'insert';
    }
    if ($type == 'insert') {
        Db::name('attachment')->where('id', $aid)->inc('count')->update();;
        Db::name('attimg')->insert(['table' => $table, 'field' => $field, 'aid' => $aid, 'fid' => $fid, 'more' => $more]);
    } else if ($type == 'update') {
        $oldAid = Db::name('attimg')->where(['table' => $table, 'fid' => $fid, 'field' => $field])->value('aid');
        if ($oldAid != $aid) {
            Db::name('attachment')->where('id', $oldAid)->dec('count')->update();;
            Db::name('attachment')->where('id', $aid)->inc('count')->update();;
            if ($oldAid) {
                Db::name('attimg')->where(['table' => $table, 'fid' => $fid, 'field' => $field])->update(['aid' => $aid]);
            } else {
                Db::name('attimg')->insert(['table' => $table, 'field' => $field, 'aid' => $aid, 'fid' => $fid]);
            }
        }
    }
}

function setAttachmentMore($table, $adis, $id)
{
    if ($adis) {
        foreach ($adis as $key => $val) {
            //取差集删除然后全部新增
            //获取原始数据
            $oldAids = Db::name('attimg')->where(['table' => $table, 'fid' => $id, 'field' => $key])->column('aid');
            $diff1 = array_diff($oldAids, $val);
            //删除差集数据同时资源表修改统计数值

            if ($diff1) {
                Db::name('attimg')->where([['table', '=', $table], ['fid', '=', $id], ['field', '=', $key], ['aid', 'in', $diff1]])->delete();
                Db::name('attachment')->where('id', 'in', $diff1)->dec('count')->update();
            }

            $diff2 = array_diff($val, $oldAids);
            if ($diff2) {
                foreach ($diff2 as $k1 => $v1) {
                    Db::name('attachment')->where('id', $v1)->inc('count')->update();;
                    Db::name('attimg')->insert(['table' => $table, 'field' => $key, 'aid' => $v1, 'fid' => $id, 'more' => 1]);
                }
            }
        }
    }
}

function delAttachment($table, $id = '')
{
    $aids = Db::name('attimg')->where([['fid', 'in', $id], ['table', '=', $table],])->column('aid');
    if ($aids) {
        foreach ($aids as $k => $v) {
            Db::name('attachment')->where('id', $v)->dec('count')->update();
        }
        Db::name('attimg')->where([['fid', 'in', $id], ['table', '=', $table],])->delete();
    }
}

/**
 * 删除目录文件
 * @param $R 文件目录
 * @return bool
 */
function deleteDir($R)
{
    $handle = opendir($R);
    while (($item = readdir($handle)) !== false) {
        if ($item != '.' and $item != '..') {
            if (is_dir($R . DIRECTORY_SEPARATOR . $item)) {
                deleteDir($R . DIRECTORY_SEPARATOR . $item);
            } else {
                if ($item != '.gitignore' && $item != 'services.php') {
                    if (!unlink($R . DIRECTORY_SEPARATOR . $item)) {
                        return false;
                    }
                }
            }
        }
    }
    closedir($handle);
    return true;
}

/**
 * 判断当前访问的用户是  PC端  还是 手机端  返回true 为手机端  false 为PC 端
 *  是否移动端访问访问
 * @return boolean
 */
function isMobile()
{
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset ($_SERVER['HTTP_X_WAP_PROFILE']))
        return true;

    // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset ($_SERVER['HTTP_VIA'])) {
        // 找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
    }
    // 脑残法，判断手机发送的客户端标志,兼容性有待提高
    if (isset ($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile');
        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT'])))
            return true;
    }
    // 协议法，因为有可能不准确，放到最后判断
    if (isset ($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return true;
        }
    }
    return false;
}

/**
 * 获取客户端浏览器信息 添加win10 edge浏览器判断
 * @param null
 * @return string
 */
function get_broswer()
{
    $sys = $_SERVER['HTTP_USER_AGENT'];  //获取用户代理字符串
    if (stripos($sys, "Firefox/") > 0) {
        $exp[0] = "Firefox";
    } elseif (stripos($sys, "Maxthon") > 0) {
        $exp[0] = "傲游";
    } elseif (stripos($sys, "MSIE") > 0) {
        $exp[0] = "IE";
    } elseif (stripos($sys, "OPR") > 0) {
        $exp[0] = "Opera";
    } else if ((strpos($sys, 'Chrome') == false) && strpos($sys, 'Safari') !== false) {
        $exp[0] = 'Safari';
    } elseif (stripos($sys, "Edge") > 0) {
        $exp[0] = "Edge";
    } elseif (stripos($sys, "Chrome") > 0) {
        $exp[0] = "Chrome";
    } elseif (stripos($sys, 'rv:') > 0 && stripos($sys, 'Gecko') > 0) {
        $exp[0] = "IE";
    } elseif (strpos($sys, 'MicroMessenger') !== false) {
        $exp[0] = "wx";
    } elseif (strpos($sys, 'QQ') !== false) {
        $exp[0] = "qq";
    } else {
        $exp[0] = "其他浏览器";
    }
    return $exp[0];
}

/***
 * 获取当前栏目ID
 * @return mixed
 */
function getCateId()
{
    if (\think\facade\Request::has('catId')) {
        $result = \think\facade\Request::param('catId');
    } else {
        $result = \app\common\model\Category::where('catdir', '=', \think\facade\Request::controller())->value('id');
    }
    return $result;
}

/***
 * 获取当前模型名（表名）
 * @return mixed
 */
function getTableName()
{
    if (\think\facade\Request::has('catId')) {
        $catId = \think\facade\Request::param('catId');
        $result = \app\common\model\Category::where('id', '=', $catId)->value('model_name');
    } else {
        $result = \app\common\model\Category::where('catdir', '=', \think\facade\Request::controller())->value('model_name');
    }
    return $result;
}

// 获取列表链接地址
function getUrl($v)
{
    if ($v['type'] == 0) {
        $modelurl = Db::name('model')
            ->where('id', $v['modelid'])
            ->value('name');
        if ($v['catdir']) {
            $v['url'] = url($v['catdir'] . '/index')->__toString();
        } else {
            $v['url'] = url($modelurl . '/index', ['cate' => $v['id']])->__toString();
        }
    }

    return $v['url'];
}

/**
 * 组合多维数组
 * @param $cate
 * @param string $name
 * @param int $pid
 * @return array
 */
function unlimitedForLayer($cate, $name = 'sub', $pid = 0)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v[$name] = unlimitedForLayer($cate, $name, $v['id']);
            $v['url'] = getUrl($v);
            $arr[] = $v;
        }
    }
    return $arr;
}

/**
 * 传递一个父级分类ID返回当前子分类
 * @param $cate
 * @param $pid
 * @return array
 */
function getChildsOn($cate, $pid)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v['sub'] = getChilds($cate, $v['id']);
            $v['url'] = getUrl($v);
            $arr[] = $v;
        }
    }
    return $arr;
}

/**
 * 传递一个父级分类ID返回所有子分类
 * @param $cate
 * @param $pid
 * @return array
 */
function getChilds($cate, $pid)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v['url'] = getUrl($v);
            $arr[] = $v;
            $arr = array_merge($arr, getChilds($cate, $v['id']));
        }
    }
    return $arr;
}

/**
 * 格式化分类数组为字符串
 * @param $ids
 * @param string $pid
 * @return string
 */
function getChildsIdStr($ids, $pid = '')
{
    $result = '';
    foreach ($ids as $k => $v) {
        $result .= $v['id'] . ',';
    }
    if ($pid) {
        $result = $pid . ',' . $result;
    }
    $result = rtrim($result, ',');
    return $result;
}

/**
 * 传递一个父级分类ID返回所有子分类ID
 * @param $cate
 * @param $pid
 * @return array
 */
function getChildsId($cate, $pid)
{
    $arr = [];
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $arr[] = $v;
            $arr = array_merge($arr, getChildsId($cate, $v['id']));
        }
    }
    return $arr;
}

/***
 * 处理数据（把列表中需要处理的字段转换成数组和对应的值,用于自定义标签文件中）
 * @param $list      列表
 * @param $modelid  模型ID
 * @return array
 */
function changeFields($list, $modelid, $model = '')
{
    $info = [];
    foreach ($list as $k => $v) {
        $url = getShowUrl($v);
        $list[$k] = changeField($v, $modelid);
        $info[$k] = $list[$k];//定义中间变量防止报错
        $info[$k]['url'] = $url;
        $info[$k]['model'] = $model;
    }
    return $info;
}

/***
 * 处理数据（用于详情页中数据转换）
 * @param $info      内容详情
 * @param $modelid  模型ID
 * @return array
 */
function changeField($info, $modelid)
{
    $fields = Db::name('field')
        ->where('modelid', '=', $modelid)
        ->select();
    foreach ($fields as $k => $v) {
        $field = $v['field'];
        if ($info[$field]) {
            switch ($v['type']) {
                case 'textarea'://多行文本
                    break;
                case 'editor'://编辑器
                    $info[$field] = $info[$field];
                    break;
                case 'select'://下拉列表
                    break;
                case 'radio'://单选按钮
                    break;
                case 'checkbox'://复选框
                    $info[$field] = explode(',', $info[$field]);
                    break;
                case 'images'://多张图片
                    $info[$field] = json_decode($info[$field], true);
                    break;
                case 'tag'://TAG标签
                    if (!empty($info[$field])) {
                        $tags = Db::name('tags')
                            ->where('id', 'IN', $info[$field])
                            ->select()->toArray();
                        foreach ($tags as $tagKey => $tag) {

                            $tags[$tagKey]['url'] = (string)url('index/tags', ['model' => $tag['model_id'], 't' => $tag['name']]);
                        }
                        $info[$field] = $tags;
                    }
                default:
            }
        }

    }
    return $info;
}


// 获取详情URL
function getShowUrl($v)
{
    if ($v) {
        $cate = \think\facade\Db::name('category')
            ->field('id,catdir,modelid')
            ->where('id', $v['catid'])
            ->find();
        $modelurl = \think\facade\Db::name('model')
            ->where('id', $cate['modelid'])
            ->value('name');
        if ($cate['catdir']) {
            $url = (string)url($cate['catdir'] . '/info', ['id' => $v['id']]);
        } else {
            $url = (string)url($modelurl . '/info', ['cate' => $cate['id'], 'id' => $v['id']]);
        }
    }
    return $url;
}


function get_sale_setting($key = "")
{
    $setting = \think\facade\Cache::remember("sale_setting", function () {
        $list = Db::name("sale_setting")->column("value", "key");
        return $list;
    });
    if (empty($key)) {
        return $setting;
    } else {
        return $setting[$key] ?? '';
    }
}

/**
 * $data array 返回数据
 * $status string 状态
 * $msg string 提示语
 */
function ajaxReturn($data = [], $status = 1, $msg = '')
{
    header('Content-Type:application/json; charset=utf-8');
    $data = $data;
    $data['status'] = $status;
    if ($msg != '') {
        $data['msg'] = $msg;
    }
    exit(json_encode($data));
}

function ajaxMsg($status = 1, $msg = '')
{
    header('Content-Type:application/json; charset=utf-8');
    $data['status'] = $status;
    $data['msg'] = $msg;
    exit(json_encode($data));
}

/**
 * @param string $openid
 * @return array|false|PDOStatement|string|\think\Model
 */
function getMemberInfo($openid = '', $field = [])
{
    if ($openid = getOrSetOpenid($openid)) {
        $user = \think\facade\Db::name('wx_mp_friends')->where(['openid' => $openid])->find();
        if (!$field) {
            return $user;
        } else {
            $fields = [];
            foreach ($field as $key => $val) {
                $fields[$val] = $user[$val];
            }
            return $fields;
        }

    }
}

/**
 * 设置、获取 openid
 */
function getOrSetOpenid($openid = '')
{
    if ($openid != '') {
        session('openid', $openid);
        return $openid;
    } else {
        $openid = session('openid');
        if ($openid) {
            return $openid;
        } else {
            return null;
        }
    }

}


/**
 * CURL请求
 * @param $url 请求url地址
 * @param $method 请求方法 get post
 * @param null $postfields post数据数组
 * @param array $headers 请求header信息
 * @param bool|false $debug 调试开启 默认false
 * @return mixed
 */
function httpRequest($url, $method, $postfields = null, $headers = array(), $debug = false)
{
    $method = strtoupper($method);
    $ci = curl_init();
    /* Curl settings */
    curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
    curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间，如果设置为0，则无限等待 */
    curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
    curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
    switch ($method) {
        case "POST":
            curl_setopt($ci, CURLOPT_POST, true);
            if (!empty($postfields)) {
                $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
                curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
            }
            break;
        default:
            curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
            break;
    }
    $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
    curl_setopt($ci, CURLOPT_URL, $url);
    if ($ssl) {
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
    }
    //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
    //curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量，这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
    curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ci, CURLINFO_HEADER_OUT, true);
    /*curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
    $response = curl_exec($ci);
    $requestinfo = curl_getinfo($ci);
    $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
    if ($debug) {
        echo "=====post data======\r\n";
        var_dump($postfields);
        echo "=====info===== \r\n";
        print_r($requestinfo);
        echo "=====response=====\r\n";
        print_r($response);
    }
    curl_close($ci);
    return $response;
    //return array($http_code, $response,$requestinfo);
}


/**
 * @param int $mid 公众号标识
 * @param string $name 配置项名称
 * @return array|false
 */
function getSetting($mid = 0, $name = '', $cate = '')
{
    $where = ['mpid' => $mid, 'name' => $name];
    if (!empty($cate)) {
        $where['cate'] = $cate;
    } else {
        $param = input();
        if (isset($param['_mid']) && !empty($param['_mid'])) {
            $where['cate'] = 'miniapp';
        } else {
            if (!empty(session('miniapp_options')) && empty(session('mp_options'))) {
                $where['cate'] = 'miniapp';
            } else {
                $where['cate'] = 'mp';
            }
        }
    }
    $model = new \app\admin\model\WxSetting();
    $result = $model->getSetting($where);
    return $result;
}

function dowloadImage($url, $save_dir = './', $filename = '', $type = 0)
{
    if (!file_exists($save_dir) && !@mkdir($save_dir, 0777, true)) {
        ajaxMsg(0, $save_dir . '目录不可写');
    }
    $ch = curl_init();
    $timeout = 5;
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    $img = curl_exec($ch);
    curl_close($ch);
    $fp2 = @fopen($save_dir . $filename, 'a');
    fwrite($fp2, $img);
    fclose($fp2);
    unset($img, $url);
    return $save_dir . $filename;
}

/**
 * 行为侦听
 * @param $name  string 行为名称
 * @param $arr array 参数
 * @author geeson myrhzq@qq.com
 */
function hook($name = '', $params = [])
{
    \think\facade\Event::trigger($name, $params);
}


/**
 *获取服务器IP
 */

function get_server_ip()
{
    if (isset($_SERVER['SERVER_NAME'])) {
        return gethostbyname($_SERVER['SERVER_NAME']);
    } else {
        if (isset($_SERVER)) {
            if (isset($_SERVER['SERVER_ADDR'])) {
                $server_ip = $_SERVER['SERVER_ADDR'];
            } elseif (isset($_SERVER['LOCAL_ADDR'])) {
                $server_ip = $_SERVER['LOCAL_ADDR'];
            }
        } else {
            $server_ip = getenv('SERVER_ADDR');
        }
        return $server_ip ? $server_ip : '获取不到服务器IP';
    }
}

//获取地址信息
function getRegion($id, $type = '1')
{
    $info = Db::name('region')->where('id', $id)->find();
    if ($type == 1) {
        return $info['name'];
    } else {
        return $info;
    }
}

/**
 * 验证输入的邮件地址是否合法
 */
function is_email($user_email)
{
    $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
    if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) {
        if (preg_match($chars, $user_email)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

//判断图片的类型从而设置图片路径
function imgUrl($img, $defaul = '')
{
    if ($img) {
        if (substr($img, 0, 4) == 'http') {
            $imgUrl = $img;
        } else {
            $imgUrl = $img;
        }
    } else {
        $imgUrl = $defaul ? $defaul : '/static/admin/images/tong.png';
    }
    return $imgUrl;
}

/**
 * 获取前N个字符
 * @param string $content
 * @param int $count
 * @return string
 */
function getWords($content, $count)
{
    $content = preg_replace("@<script(.*?)</script>@is", "", $content);
    $content = preg_replace("@<iframe(.*?)</iframe>@is", "", $content);
    $content = preg_replace("@<style(.*?)</style>@is", "", $content);
    $content = preg_replace("@<(.*?)>@is", "", $content);
    $content = str_replace(PHP_EOL, '', $content);
    $space = array(" ", "　", "    ", " ", " ");
    $go_away = array("", "", "", "", "");
    $content = str_replace($space, $go_away, $content);
    $res = mb_substr($content, 0, $count, 'UTF-8');
    if (mb_strlen($content, 'UTF-8') > $count) {
        $res = $res . "...";
    }
    return $res;
}

/**
 * 获取表字段
 * @param $table 表名
 * @return array
 */
function getTableFields($table)
{
    $table = Db::name($table)->getFields();
    $info = [];
    foreach ($table as $k => $v) {
        $info[$k] = $v['default'];
    }
    return $info;
}

/**
 * 传递一个子分类ID返回所有的父级分类
 * @param $cate
 * @param $id
 * @return array
 */
function getParents($cate, $id)
{
    $arr = array();
    foreach ($cate as $v) {
        if ($v['id'] == $id) {
            $arr[] = $v;
            $arr = array_merge(getParents($cate, $v['pid']), $arr);
        }
    }
    return $arr;
}

/**
 * 检测图片是否包含木马
 * @param $image 图片路径
 * @return
 */
function checkHex($image)
{
    if (file_exists($image)) {
        $resource = fopen($image, 'rb');
        $fileSize = filesize($image);
        fseek($resource, 0);
        if ($fileSize > 512) { // 取头和尾
            $hexCode = bin2hex(fread($resource, 512));
            fseek($resource, $fileSize - 512);
            $hexCode .= bin2hex(fread($resource, 512));
        } else { // 取全部
            $hexCode = bin2hex(fread($resource, $fileSize));
        }
        fclose($resource);
        /* 匹配16进制中的 <% ( ) %> */
        /* 匹配16进制中的 <? ( ) ?> */
        /* 匹配16进制中的 <script | /script> 大小写亦可*/
        if (preg_match("/(3c25)|(3c3f.*?706870)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode)) {
            $status = 1;
        } else {
            $status = 0;
        }
        return $status;
    } else {
        return $status = 1;
    }
}

function tomedia($src)
{
    return strpos($src, 'http') === false ? request()->domain(true) . $src : $src;
}

function get_region($data, $pid)
{
    $list = [];
    foreach ($data as $item) {
        $t = [];
        if ($item['pid'] == $pid) {
            $t['value'] = $item['id'];
            $t['label'] = $item['name'];
            if (get_region($data, $item['id'])) {
                $t['children'] = get_region($data, $item['id']);
            }
            array_push($list, $t);
        }
    }
    return $list;
}

function show_star($str, $start, $end)
{
    return substr_replace($str, "****", $start, $end);
}


function show_datetime($time = "")
{
    if (empty($time)) {
        return "";
    }
    return date('Y-m-d H:i:s', $time);
}

//获取系统配置信息
function get_system_config($key = "")
{
    $system = \think\facade\Cache::remember("system_config", function () {
        $system = \app\common\model\System::getListField()->toArray();
        $data = [];
        foreach ($system as $item) {
            $data[$item['field']] = $item['value'];
        }
        return $data;
    });
    if (empty($key)) {
        return $system;
    } else {
        return $system[$key] ?? "";
    }
}

function getWeekDate($year, $weeknum)
{
    $firstdayofyear = mktime(0, 0, 0, 1, 1, $year);
    $firstweekday = date('N', $firstdayofyear);
    $firstweenum = date('W', $firstdayofyear);
    if ($firstweenum == 1) {
        $day = (1 - ($firstweekday - 1)) + 7 * ($weeknum - 1);
        $startdate = date('Y-m-d', mktime(0, 0, 0, 1, $day, $year));
        $enddate = date('Y-m-d', mktime(0, 0, 0, 1, $day + 6, $year));
    } else {
        $day = (9 - $firstweekday) + 7 * ($weeknum - 1);
        $startdate = date('Y-m-d', mktime(0, 0, 0, 1, $day, $year));
        $enddate = date('Y-m-d', mktime(0, 0, 0, 1, $day + 6, $year));
    }

    return array($startdate, $enddate);
}

function is_json($str){
    @json_decode($str);
    $err = json_last_error();
    if($err == JSON_ERROR_NONE){
        return false;
    }else{
        return true;
    }
}